package name.zeno.qrcode.library

import android.app.Activity
import android.app.Fragment
import android.content.Intent
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.JELLY_BEAN_MR1
import android.os.Parcelable
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject

/**
 * @author 陈治谋 (513500085@qq.com)
 * @since 2017/12/5
 */
internal class NavFragment : Fragment() {
  var sub = PublishSubject.create<Any>()

  var onResult: ((ok: Boolean, data: Intent?) -> Unit)? = null

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (CODE == requestCode) {
      onResult?.invoke(resultCode == Activity.RESULT_OK, data)
    }
  }

  override fun onResume() {
    super.onResume()
    if (sub.hasComplete().not()) {
      sub.onNext(this)
      sub.onComplete()
    }
  }

  fun navForResult(target: Class<out Activity>, data: Parcelable? = null, onResult: ((ok: Boolean, data: Intent?) -> Unit)? = null) {
    (if (isResumed) Observable.just(this) else sub).subscribe {
      this.onResult = onResult
      val intent = Intent(activity, target)
      intent.putExtra("data", data)
      startActivityForResult(Intent(activity, target), CODE)
    }
  }

  companion object {
    const val TAG: String = "name.zeno.qrcode.library.NavFragment"
    const val CODE = 0xff01

    fun with(fragment: Fragment): NavFragment {
      val fm = if (SDK_INT > JELLY_BEAN_MR1) fragment.childFragmentManager else fragment.fragmentManager
      val instance = fm.findFragmentByTag(TAG) as? NavFragment
      if (instance != null) return instance

      val new = NavFragment()
      fm.beginTransaction().add(new, TAG).commit()
      return new
    }


    fun with(activity: Activity): NavFragment {
      val fm = activity.fragmentManager
      val instance = fm.findFragmentByTag(TAG) as? NavFragment
      if (instance != null) return instance

      val new = NavFragment()
      fm.beginTransaction().add(new, TAG).commit()
      return new
    }
  }
}